package com.bianqian.demo.repository;

import com.bianqian.demo.entity.Note;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 笔记数据访问层
 */
@Repository
public interface NoteRepository extends JpaRepository<Note, Long> {
    
    /**
     * 根据用户ID查找所有未删除的笔记
     * @param userId 用户ID
     * @return 笔记列表
     */
    List<Note> findByUserIdAndIsDeletedFalseOrderByIsPinnedDescCreatedAtDesc(Long userId);
    
    /**
     * 根据用户ID分页查找所有未删除的笔记
     * @param userId 用户ID
     * @param pageable 分页参数
     * @return 笔记分页列表
     */
    Page<Note> findByUserIdAndIsDeletedFalseOrderByIsPinnedDescCreatedAtDesc(Long userId, Pageable pageable);
    
    /**
     * 根据用户ID和关键词搜索笔记
     * @param userId 用户ID
     * @param keyword 关键词
     * @param pageable 分页参数
     * @return 笔记分页列表
     */
    @Query("SELECT n FROM Note n WHERE n.userId = :userId AND n.isDeleted = false AND " +
           "(n.title LIKE %:keyword% OR n.content LIKE %:keyword%) " +
           "ORDER BY n.isPinned DESC, n.createdAt DESC")
    Page<Note> findByUserIdAndKeyword(@Param("userId") Long userId, @Param("keyword") String keyword, Pageable pageable);
    
    /**
     * 根据用户ID和分类名称查找笔记
     * @param userId 用户ID
     * @param categoryName 分类名称
     * @param pageable 分页参数
     * @return 笔记分页列表
     */
    @Query("SELECT n FROM Note n JOIN Category c ON n.categoryId = c.id " +
           "WHERE n.userId = :userId AND n.isDeleted = false AND c.name = :categoryName " +
           "ORDER BY n.isPinned DESC, n.createdAt DESC")
    Page<Note> findByUserIdAndCategoryName(@Param("userId") Long userId, @Param("categoryName") String categoryName, Pageable pageable);
    
    /**
     * 根据用户ID和置顶状态查找笔记
     * @param userId 用户ID
     * @param isPinned 是否置顶
     * @param pageable 分页参数
     * @return 笔记分页列表
     */
    Page<Note> findByUserIdAndIsPinnedAndIsDeletedFalseOrderByCreatedAtDesc(Long userId, Boolean isPinned, Pageable pageable);
    
    /**
     * 根据分类ID查找所有未删除的笔记
     * @param categoryId 分类ID
     * @return 笔记列表
     */
    List<Note> findByCategoryIdAndIsDeletedFalseOrderByCreatedAtDesc(Long categoryId);
    
    /**
     * 根据用户ID和分类ID查找所有未删除的笔记
     * @param userId 用户ID
     * @param categoryId 分类ID
     * @return 笔记列表
     */
    List<Note> findByUserIdAndCategoryIdAndIsDeletedFalseOrderByCreatedAtDesc(Long userId, Long categoryId);
    
    /**
     * 统计分类下的笔记数量
     * @param categoryId 分类ID
     * @return 笔记数量
     */
    @Query("SELECT COUNT(n) FROM Note n WHERE n.categoryId = :categoryId AND n.isDeleted = false")
    Long countByCategoryId(@Param("categoryId") Long categoryId);
    
    /**
     * 根据用户ID删除所有笔记（软删除）
     * @param userId 用户ID
     */
    @Modifying
    @Query("UPDATE Note n SET n.isDeleted = true WHERE n.userId = :userId")
    void softDeleteByUserId(@Param("userId") Long userId);
    
    /**
     * 查找用户指定时间后更新的笔记
     * @param userId 用户ID
     * @param lastSyncTime 最后同步时间
     * @return 笔记列表
     */
    @Query("SELECT n FROM Note n WHERE n.userId = :userId AND n.isDeleted = false AND n.updatedAt > :lastSyncTime ORDER BY n.updatedAt DESC")
    List<Note> findUpdatedNotesAfter(@Param("userId") Long userId, @Param("lastSyncTime") LocalDateTime lastSyncTime);
    
    /**
     * 查找用户指定时间后创建的笔记
     * @param userId 用户ID
     * @param lastSyncTime 最后同步时间
     * @return 笔记列表
     */
    @Query("SELECT n FROM Note n WHERE n.userId = :userId AND n.isDeleted = false AND n.createdAt > :lastSyncTime ORDER BY n.createdAt DESC")
    List<Note> findNewNotesAfter(@Param("userId") Long userId, @Param("lastSyncTime") LocalDateTime lastSyncTime);
}


